package codigoGerado;

import java_cup.runtime.*;
import core.exceptions.*;
import core.types.*;

%%

%class LexicalAnalyzer
%public
%column
%line
%cup

%{
	private Symbol symbol(int type) {
		return new Symbol(type, yyline, yycolumn);
	}
   	
	private Symbol symbol(int type, Object val) {
		return new Symbol(type, yyline, yycolumn, val);
	}

	private void mensagemErro() {
		throw new LexicalException(ExceptionFormat.LEXICAL, yyline + 1, yycolumn + 1, yytext());
	}
%}

upper_case_letter = [A-Z]
lower_case_letter = [a-z]
identifier_letter = {upper_case_letter} | {lower_case_letter}

octaldigit = [0-7]
digit = {octaldigit} | [8-9]
hexdigit = {digit} | "A" | "B" | "C" | "D" | "E" | "F" 

ident = {identifier_letter} ({identifier_letter} | {digit})*
integer = ( {digit} ({digit})* ) | 
      ( {octaldigit} ({octaldigit})* ( "B" | "C" ) ) | 
      ( {digit} ({hexdigit}) "H" )
      
scale_factor = "E" ["+" | "-"]? {digit} ({digit})*
real = ({digit})+ "." ({digit})+ ({scale_factor})? 

string = ("'" ([^'])* } "'") | 
      ( "\"" ([^\"])* "\"" )

WhiteSpace=[ \r\n\t\f]
COMMENT="(*"([^\*\)])*"*)"

%%

<YYINITIAL>{
	{WhiteSpace}		{ 											}
	{COMMENT}			{											}
	{string}			{ return symbol(sym.string, yytext());		}

	"AND"				{ return symbol(sym.AND);					}
	"ARRAY"				{ return symbol(sym.ARRAY);					}
	"BEGIN"				{ return symbol(sym.BEGIN);					}
	"BY"				{ return symbol(sym.BY);					}
	"CONST"				{ return symbol(sym.CONST);					}
	"DIV"				{ return symbol(sym.DIV);					}
	"DO"				{ return symbol(sym.DO);					}
	"ELSE"				{ return symbol(sym.ELSE);					}
	"ELSIF"				{ return symbol(sym.ELSIF);					}
	"END"				{ return symbol(sym.END);					}
	"EXIT"				{ return symbol(sym.EXIT);					}
	"FOR"				{ return symbol(sym.FOR);					}
	"FROM"				{ return symbol(sym.FROM);					}
	"IF"				{ return symbol(sym.IF);					}
	"IMPORT"			{ return symbol(sym.IMPORT);				}
	"IN"				{ return symbol(sym.IN);					}
	"MOD"				{ return symbol(sym.MOD);					}
	"MODULE"			{ return symbol(sym.MODULE);				}
	"NOT"				{ return symbol(sym.NOT);					}
	"OF"				{ return symbol(sym.OF);					}
	"OR"				{ return symbol(sym.OR);					}
	"PROCEDURE"			{ return symbol(sym.PROCEDURE);				}
	"RETURN"			{ return symbol(sym.RETURN);				}
	"THEN"				{ return symbol(sym.THEN);					}
	"TO"				{ return symbol(sym.TO);					}
	"VAR"				{ return symbol(sym.VAR);					}
	"WHILE"				{ return symbol(sym.WHILE);					}

	"BOOLEAN"			{ return symbol(sym.BOOLEAN, yytext());		}
	"CHAR"				{ return symbol(sym.CHAR, yytext());		}
	"INTEGER"			{ return symbol(sym.INTEGER, yytext());		}
	"LONGINT"			{ return symbol(sym.LONGINT, yytext());		}
	"REAL"				{ return symbol(sym.REAL, yytext());		}
	"LONGREAL"			{ return symbol(sym.LONGREAL, yytext());	}
	"TRUE"				{ return symbol(sym.TRUE);					}
	"FALSE"				{ return symbol(sym.FALSE);					}

	"(" 				{ return symbol(sym.LeftParenthesis); 		}
	")"			 		{ return symbol(sym.RightParenthesis); 		}
	">="		 		{ return symbol(sym.GreaterThanOrEqualsTo); }
	"<="		 		{ return symbol(sym.LessThanOrEqualsTo); 	}
	"<>"		 		{ return symbol(sym.NotEqualsTo); 			}
	"="			 		{ return symbol(sym.EqualsTo); 				}
	">"			 		{ return symbol(sym.GreaterThan);			}
	"<"			 		{ return symbol(sym.LessThan); 				}
	"+"			 		{ return symbol(sym.Addition); 				}
	"-" 				{ return symbol(sym.Subtraction); 			}
	"*" 				{ return symbol(sym.Multiplication);		}
	"/"			 		{ return symbol(sym.Division);				}
	":"					{ return symbol(sym.Colon); 				}
	";"					{ return symbol(sym.SemiColon); 			}
	":="				{ return symbol(sym.Assign); 				}
	".."				{ return symbol(sym.Dots);					}
	"."					{ return symbol(sym.Dot);					}
	","					{ return symbol(sym.Comma);					}
	"["					{ return symbol(sym.LeftSquareBracket);		}
	"]"					{ return symbol(sym.RightSquareBracket);	}
	"#"					{ return symbol(sym.Hash);					}
	"^"					{ return symbol(sym.Caret);					}
	"&"					{ return symbol(sym.Ampersand);				}

	{integer}			{ return symbol(sym.NINTEGER, yytext());		}
	{real}				{ return symbol(sym.NREAL, yytext());		}
	{ident}				{ return symbol(sym.ident, yytext()); 		}
}

<<EOF>> 			{ return symbol(sym.EOF); 					}
.|\n 				{ mensagemErro();							}